package mystudy
// 切片
import "fmt"
var DDD int = 100
func DemoSlice(){
	println(DDD)
	// 1.声明一个空切片
	var slice []int
	// 空切片使用append进行赋值
	slice = append(slice,11)
	fmt.Println(slice)
	// 2.声明一个赋值的切片 由数组创建一个切片
	var slice1 [6]int = [6]int{1,3,45,34,54}
	// 切片一个长度:左闭右开 根据下标切片
	slice2 := slice1[1:3]
	fmt.Println(slice2, len(slice2), len(slice1))
	// 获取切片的容量 大约是现有数据的2倍
	fmt.Println(cap(slice1), cap(slice2))
	println(&slice1)
	fmt.Printf("slice1:%p\n", &slice1[0])
	slice1[1] = 1000
	fmt.Println(slice1)
	// 切片的结构体
	type slice3 struct{
		address *int// 首元素地址
		length int// 长度
		capp int// 容量
	}
	// 3.切片的长度
	fmt.Println("切片的长度：", len(slice1))
	fmt.Println("切片的容量：",cap(slice1))
	// 4.make创建切片 1.切片类型 2切片长度 3切片容量
	// make(type, len, cap ) 其实make
	var sliceByMake1 []int = make([]int, 1, 1)
	fmt.Println("sliceByMake1切片的长度：", len(sliceByMake1))
	fmt.Println("sliceByMake1切片的容量：",cap(sliceByMake1))
	var sliceByMake2 = make([]int, 1, 1)
	fmt.Println("sliceByMake1切片的长度：", len(sliceByMake2))
	fmt.Println("sliceByMake1切片的容量：",cap(sliceByMake2))
	/*
	在Go语言中，使用make函数创建切片时，底层会进行以下操作：
	1.分配底层数组（Underlying Array）：make函数会分配一个底层数组，该数组将用于存储切片的元素。
	2.初始化切片结构：make函数会创建一个切片结构，并将其与底层数组关联起来。
		切片结构包含了指向底层数组的指针、切片的长度和切片的容量。
	3.返回切片：make函数返回创建的切片，可以通过变量来引用该切片。
	*/
	// 切片的三种创建方式
	// 1.由数组转为切片
	var arryToSlice [10]int = [10]int{1, 2, 3, 5}
	slice11 := arryToSlice[:8]
	fmt.Println(slice11)
	fmt.Printf("slice11 的类型:%T\n", slice11)
	// 2.直接定义
	var slice22 = []int{1, 6, 8}
	fmt.Println(slice22)
	fmt.Printf("slice22 的类型:%T\n", slice22)
	// 3.使用make定义
	var slice33 = make([]int, 1, 2)
	fmt.Println(slice33)
	fmt.Printf("slice33 的类型:%T\n", slice33)

	fmt.Println("slice22 数组的长度：", len(slice22))
	fmt.Println("slice22 数组的容量：", cap(slice22))
	// 切片的遍历
	// 1.for函数遍历
	for i:=0; i<len(slice11); i++{
		fmt.Println(slice11[i])
	}
	// 2.for-range遍历
	for i,v := range slice11{
		fmt.Println("i,v", i, v)
	}
	defer func(){
		if err:=recover(); err != nil{
			fmt.Println("出现了异常，应该执行这里", err)
			fmt.Println("异常结束")
		}
	}()
	// 切片与数组的区别的注意事项
	// 1. 一个切片赋值给另一个切片是引用，其中一个修改，另一个也会修改
	// 数组赋值是复制，其中一个改变另一个不会改变
	/// 切片
	var aa11 = []int{1,2,2}
	aa22 := aa11
	fmt.Printf("%T, %v\n", aa22, aa22)
	fmt.Println(aa22, aa11)
	aa22[1] = 444
	fmt.Println(aa22, aa11)
	// 1.数组
	var bb11 = [...]int{1,2,3}
	bb22 := bb11
	fmt.Println(bb22, bb11)
	bb22[1] = 444
	fmt.Println(bb22, bb11)
	// 2.注意切片越界，编译时不会检测出来，而数组越界，会被检测出来
	// 3.数组可以使用切片方式变成切片
	aa33 := bb22[:1]
	fmt.Printf("%T", aa33)
	// 切片的简写方式
	fmt.Println(aa33[:])
	// 切片追加元素: 底层原理，老数组
	aa66 := append(aa33, 12, 33, 44,55)
	fmt.Println(aa33, aa66)
	// 追加一个切片使用 ... 即可
	aa66 = append(aa66, aa66...)
	fmt.Println(aa66)
	// 切片的拷贝, 前面我们使用直接赋值是引用，
	// 那么如果完全拷贝出来一个呢，需要使用copy这个函数进行
	
}